<template>
  <view class="receiving-method" @click="toggle">
    <span class="base" :class="{ active: isLeftActive }">{{
      isLeftActive ? (activeName ?? optionsData.left.name) : optionsData.left.name
    }}</span>
    <span class="base" :class="{ active: !isLeftActive }">{{
      !isLeftActive ? (activeName ?? optionsData.right.name) : optionsData.right.name
    }}</span>
  </view>
  <receiving-method-select v-model:options="chooseItems" v-model="currentReceivingMethod" />
</template>

<script setup lang="ts">
import { type Ref, ref, watch, computed } from 'vue'
import ReceivingMethodSelect from './receiving-method-select/index.vue'
import type { ReceivingMethodObject } from './type'
import $store from '@/store'
import { ReceivingMethod } from '@/enum/ReceivingMethod'
const emits = defineEmits<{
  (e: 'update:modelValue', value: number): void
}>()
const props = defineProps({
  modelValue: {
    type: Number,
    require: true
  },
  super: {
    type: String
  }
})

// 当前显示
const activeName = ref<string | null>(null)
// 经过处理的props.super
const parsedSuper = ref<Array<string>>()
// 当前选择的配送方式
const currentReceivingMethod = $store.shop.receivingMethod.getRef()
// 进行触发选择的
const chooseItems = ref<ReceivingMethodObject[]>()
// 场景与ReceivingMethod的映射
const sceneAndReceivingMethodMap: { [key: string]: string[] } = {
  in_store_QR_code_scanning: [ReceivingMethod.SELF_PICKUP, ReceivingMethod.SHOP_EAT] // 店下扫码：让用户选择自提、店食
}
watch(
  () => props.super,
  (newSuper) => {
    if (newSuper != null) {
      parsedSuper.value = newSuper.split(',')
    }
    // 触发初始化currentReceivingMethod的值操作
    receivingMethodDecision(tryInitReceivingMethod())
  },
  { immediate: true }
)
// 具有结构化optionsMap
const optionsData = ref<{ [key: string]: ReceivingMethodObject }>({
  left: {
    name: '配送',
    value: ReceivingMethod.DELIVERY
  },
  right: {
    name: '到店',
    children: [
      {
        name: '店食',
        value: ReceivingMethod.SHOP_EAT
      },
      {
        name: '自提',
        value: ReceivingMethod.SELF_PICKUP
      }
    ]
  }
})
// 平面化的optionsData（ value : {name:string,value:string}）
const optionsMap = (function () {
  const items: ReceivingMethodObject[] = Object.values(optionsData.value)
  const result: { [key: string]: ReceivingMethodObject } = {}
  for (let item of items) {
    if (item.value != null) {
      result[item.value] = item
    } else if (item.children != null && item.children.length > 0) {
      for (let childrenItem of item.children) {
        result[childrenItem.value] = childrenItem
      }
    }
  }
  return result
})()
// 选择的与店铺支持的取交集
function safeFilter(inputReceivingMethod: string | Array<string>) {
  let shopSuperReceivingMethod = parsedSuper.value
  if (
    inputReceivingMethod === '' ||
    inputReceivingMethod == null ||
    (Array.isArray(inputReceivingMethod) && inputReceivingMethod.length === 0) ||
    shopSuperReceivingMethod == null
  ) {
    return []
  }
  let processedInputReceivingMethod: string[] = []

  if (Array.isArray(inputReceivingMethod)) {
    processedInputReceivingMethod = inputReceivingMethod
  } else if (typeof inputReceivingMethod === 'string') {
    processedInputReceivingMethod = (inputReceivingMethod as string).split(',')
  }
  // 取交集
  return processedInputReceivingMethod.filter((value) => shopSuperReceivingMethod!.includes(value))
}

watch(
  () => currentReceivingMethod.value,
  (newVal) => {
    if (newVal != null) {
      // 更新page数据ReceivingMethod
      $store.shop.receivingMethod.setValue(newVal)
      activeName.value = optionsMap[newVal].name
    }
  },
  { immediate: true }
)
// 判断左右边是否活跃
const isLeftActive = computed(() => optionsData.value.left.value === currentReceivingMethod.value)

// 初始化initReceivingMethod的值
function tryInitReceivingMethod(): string[] {
  // 根据“店内扫码场景”取值
  const seatNumber = $store.shop.seatNumber.getValue()
  if (seatNumber != null && seatNumber !== '') {
    const receivingMethodStr = sceneAndReceivingMethodMap['in_store_QR_code_scanning']
    if (receivingMethodStr != null) {
      return safeFilter(receivingMethodStr)
    }
  }
  // 根据店家支持取值
  if (parsedSuper.value != null && parsedSuper.value?.length > 0) {
    if (
      parsedSuper.value?.length === 2 &&
      parsedSuper.value.find((value) => value === ReceivingMethod.DELIVERY) == null
    ) {
      return parsedSuper.value
    }
    return [parsedSuper.value[0]]
  }
  return []
}
// 调起让用户选择
async function triggerUserChooseReceivingMethod(receivingMethods: string[]) {
  // 映射为需要的数据
  chooseItems.value = receivingMethods.map((receivingMethod) => optionsMap[receivingMethod])
}
// 触发最终决定(如果包含多个结果，触发让用户选择)
function receivingMethodDecision(receivingMethods: string[]) {
  if (receivingMethods.length === 0) return
  // 触发调用弹窗让用户选择
  choose(receivingMethods, false)
}

// 准备调起选择
function choose(receivingMethodValue: string[], isManual = true) {
  const receivingMethodValueBack = JSON.parse(JSON.stringify(receivingMethodValue))
  const validReceivingMethods = safeFilter(receivingMethodValue)
  if (validReceivingMethods == null || validReceivingMethods.length === 0) {
    if (isManual)
      uni.showToast({
        icon: 'none',
        title: '店铺不支持' + (isLeftActive.value ? optionsData.value.right.name : optionsData.value.left.name)
      })
    return
  }
  if (validReceivingMethods.length === 1) {
    currentReceivingMethod.value = validReceivingMethods[0]
  } else {
    // 调起选择
    triggerUserChooseReceivingMethod(validReceivingMethods)
  }
}
function parseReceivingMethodValue(receivingMethod: ReceivingMethodObject): string[] {
  if (receivingMethod.value != null) {
    return [receivingMethod.value]
  } else if (receivingMethod.children != null) {
    return receivingMethod.children.map((item) => item.value)
  }
  return []
}
function toggle() {
  choose(
    isLeftActive.value
      ? parseReceivingMethodValue(optionsData.value.right)
      : parseReceivingMethodValue(optionsData.value.left)
  )
}
</script>

<style scoped lang="scss">
$control-height: 44rpx;
$control-radius-size: $control-height * 0.5;
$control-padding-size: 9rpx;
$control-child-radius-size: ($control-height - $control-padding-size * 2) * 0.5;

.receiving-method {
  display: flex;
  align-items: center;
  overflow: hidden;
  padding: 8rpx;
  height: $control-height;
  font-size: 23rpx;
  font-weight: 700;
  border-radius: $control-radius-size;
  color: #fff;
  background-color: #6e6e6ebe;
  line-height: $control-height;

  .base {
    padding: 0rpx 15rpx;
  }

  .active {
    border-radius: $control-child-radius-size;
    background-color: #fbc02d;
  }
}
</style>
